import os
import json
import shutil
from flask import Flask, render_template, request, jsonify, send_from_directory
from chains import comprehensive_evaluation
from werkzeug.utils import secure_filename
# 添加并发处理相关导入
from concurrent.futures import ThreadPoolExecutor, as_completed
import threading

app = Flask(__name__, template_folder='templates', static_folder='static')

DATA_DIR = os.path.join(os.path.dirname(__file__), 'data')
OUTPUT_DIR = os.path.join(os.path.dirname(__file__), 'output')

# 确保目录存在
os.makedirs(DATA_DIR, exist_ok=True)
os.makedirs(OUTPUT_DIR, exist_ok=True)

# 添加全局线程池执行器
executor = ThreadPoolExecutor(max_workers=5)

@app.route('/')
def index():
    return render_template('index.html')

# 获取文件列表
@app.route('/api/files')
def list_files():
    data_files = []
    output_files = []
    
    # 获取数据文件
    for filename in os.listdir(DATA_DIR):
        if filename.endswith('.json'):
            filepath = os.path.join(DATA_DIR, filename)
            stat = os.stat(filepath)
            data_files.append({
                'name': filename,
                'size': stat.st_size,
                'modified': stat.st_mtime
            })
    
    # 获取输出文件
    for filename in os.listdir(OUTPUT_DIR):
        if filename.endswith('.json'):
            filepath = os.path.join(OUTPUT_DIR, filename)
            stat = os.stat(filepath)
            output_files.append({
                'name': filename,
                'size': stat.st_size,
                'modified': stat.st_mtime
            })
    
    return jsonify({
        'data_files': sorted(data_files, key=lambda x: x['modified'], reverse=True),
        'output_files': sorted(output_files, key=lambda x: x['modified'], reverse=True)
    })

# 上传文件
@app.route('/api/upload', methods=['POST'])
def upload_file():
    # 支持单个或多个文件上传（例如浏览器目录选择会发送多个 file）
    files = []
    if 'file' in request.files:
        files = request.files.getlist('file')
    elif len(request.files) > 0:
        # 兼容其它情况下直接上传的文件集合
        files = list(request.files.values())
    else:
        return jsonify({'error': 'No file provided'}), 400

    saved = []
    errors = []

    for file in files:
        if not file or not file.filename:
            continue
        filename = secure_filename(file.filename)
        if not filename.lower().endswith('.json'):
            errors.append({'filename': filename, 'error': 'Invalid file format'})
            continue
        try:
            filepath = os.path.join(DATA_DIR, filename)
            file.save(filepath)
            saved.append(filename)
        except Exception as e:
            errors.append({'filename': filename, 'error': str(e)})

    if len(saved) == 0 and len(errors) > 0:
        return jsonify({'error': 'No files saved', 'errors': errors}), 400

    return jsonify({'message': 'Files uploaded successfully', 'saved': saved, 'errors': errors})

# 删除文件
@app.route('/api/delete/<file_type>/<filename>', methods=['DELETE'])
def delete_file(file_type, filename):
    if file_type not in ['data', 'output']:
        return jsonify({'error': 'Invalid file type'}), 400
    
    directory = DATA_DIR if file_type == 'data' else OUTPUT_DIR
    filepath = os.path.join(directory, filename)
    
    if os.path.exists(filepath):
        os.remove(filepath)
        return jsonify({'message': 'File deleted successfully'})
    
    return jsonify({'error': 'File not found'}), 404

# 下载文件
@app.route('/api/download/<file_type>/<filename>')
def download_file(file_type, filename):
    if file_type not in ['data', 'output']:
        return jsonify({'error': 'Invalid file type'}), 400
    
    directory = DATA_DIR if file_type == 'data' else OUTPUT_DIR
    return send_from_directory(directory, filename, as_attachment=True)

# 获取文件内容
@app.route('/api/content/<file_type>/<filename>')
def get_file_content(file_type, filename):
    if file_type not in ['data', 'output']:
        return jsonify({'error': 'Invalid file type'}), 400
    
    directory = DATA_DIR if file_type == 'data' else OUTPUT_DIR
    filepath = os.path.join(directory, filename)
    
    if not os.path.exists(filepath):
        return jsonify({'error': 'File not found'}), 404
    
    try:
        with open(filepath, 'r', encoding='utf-8') as f:
            content = json.load(f)
        return jsonify(content)
    except Exception as e:
        return jsonify({'error': str(e)}), 500

# 运行质控流程
@app.route('/api/run-quality-control/<filename>')
def run_quality_control(filename):
    filepath = os.path.join(DATA_DIR, filename)
    if not os.path.exists(filepath):
        return jsonify({'error': 'File not found'}), 404
    
    try:
        result = comprehensive_evaluation(filepath)
        return jsonify(result)
    except Exception as e:
        return jsonify({'error': str(e)}), 500

# 添加批量运行质控流程接口
@app.route('/api/run-quality-control-batch', methods=['POST'])
def run_quality_control_batch():
    try:
        data = request.get_json()
        filenames = data.get('filenames', [])
        concurrency = data.get('concurrency', 3)
        
        if not filenames:
            return jsonify({'error': 'No files provided'}), 400
            
        # 限制最大并发数
        concurrency = min(concurrency, 10)
        
        # 使用线程池并发处理
        def process_single_file(filename):
            filepath = os.path.join(DATA_DIR, filename)
            if not os.path.exists(filepath):
                return {'filename': filename, 'error': 'File not found'}
            
            try:
                result = comprehensive_evaluation(filepath)
                return {'filename': filename, 'result': result}
            except Exception as e:
                return {'filename': filename, 'error': str(e)}
        
        results = []
        with ThreadPoolExecutor(max_workers=concurrency) as executor:
            future_to_filename = {
                executor.submit(process_single_file, filename): filename 
                for filename in filenames
            }
            
            for future in as_completed(future_to_filename):
                try:
                    result = future.result()
                    results.append(result)
                except Exception as e:
                    filename = future_to_filename[future]
                    results.append({'filename': filename, 'error': str(e)})
        
        return jsonify({'results': results})
    except Exception as e:
        return jsonify({'error': str(e)}), 500

# 写入日志
@app.route('/api/write-log', methods=['POST'])
def write_log():
    try:
        data = request.get_json()
        message = data.get('message', '')
        
        log_file_path = os.path.join(os.path.dirname(__file__), 'log.txt')
        with open(log_file_path, 'a', encoding='utf-8') as f:
            f.write(message)
        
        return jsonify({'status': 'success'})
    except Exception as e:
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)
